package work.huangxin.share.controller.sechand;


import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Strings;
import io.minio.errors.*;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.multipart.MultipartFile;
import work.huangxin.share.constant.RedisConstant;
import work.huangxin.share.domain.other.WXSessionModel;
import work.huangxin.share.domain.sechand.SechandGoods;
import work.huangxin.share.service.SechandGoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import work.huangxin.share.service.impl.UserMessageOperationService;
import work.huangxin.share.service.impl.MinioSysFileServiceImpl;
import work.huangxin.share.util.RedisUtil;
import work.huangxin.share.util.ThreadLocalUtil;
import work.huangxin.share.util.common.JsonUtils;
import work.huangxin.share.util.status.BaseResponse;
import work.huangxin.share.util.status.CodeEnum;
import work.huangxin.share.util.status.ResponseData;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * (SechandGoods) 控制层
 *
 * @author 张锦标
 * @since 2023-03-23 10:35:10
 */
@RestController
@RequestMapping("/wx/sechandGoods")
public class SechandGoodsController {

    @Autowired
    private SechandGoodsService sechandGoodsService;
    @Autowired
    private UserMessageOperationService userMessageOperationService;

    @Autowired
    private MinioSysFileServiceImpl minioSysFileService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     * 随机展示首页分页数据
     */
    @GetMapping("/getGoodsPage")
    public BaseResponse getPageByRandom(@RequestParam Integer pageSize, @RequestParam Integer pageNo) {
        //首页数据从缓存中得到
        PageInfo<SechandGoods> sechandGoodsPageInfo = (PageInfo<SechandGoods>) redisUtil.get(RedisConstant.GOOD__PAGE_NO + pageNo.toString());
        if (Objects.isNull(sechandGoodsPageInfo)) {
            //缓存未命中
            PageInfo<SechandGoods> sechandGoodsPageInfoFromDB = sechandGoodsService.selectPageSechandGoodsList(pageNo, pageSize);
            if (Objects.isNull(sechandGoodsPageInfoFromDB)) {
                return ResponseData.out(CodeEnum.NOT_FOUND, "首页数据丢失");
            }
            redisUtil.set(RedisConstant.GOOD__PAGE_NO+pageNo.toString(), sechandGoodsPageInfoFromDB, 60*10);
            return ResponseData.success(sechandGoodsPageInfoFromDB);
        }
        return ResponseData.success(sechandGoodsPageInfo);
    }

    /**
     * 用户查询自己的闲置商品
     */
    @GetMapping("/getGoodsByUser")
    public BaseResponse getGoodsByUserId(HttpServletRequest request) {
        WXSessionModel user = (WXSessionModel) request.getSession().getAttribute("user");
        Long userId = ThreadLocalUtil.get();
        WXSessionModel user1 = (WXSessionModel) redisUtil.get("user:" + userId);
        if (user.getUserId() < 0) {
            return ResponseData.error(403, "用户身份异常");
        }
        List<SechandGoods> sechandGoodsByUserId = sechandGoodsService.selectSechandGoodsByUserId(user.getUserId());
        if (Objects.isNull(sechandGoodsByUserId)) {
            return ResponseData.out(CodeEnum.NOT_FOUND, "用户商品查询失败");
        }
        return ResponseData.success(sechandGoodsByUserId);
    }

    /**
     * 查看商品详情
     *
     * @param id
     * @return
     */
    @GetMapping("/getGoodsById/{id}")
    public BaseResponse getGoodsById(@PathVariable Long id) {
        //从缓存中得到
        String sechandGoodsFromRedis = redisTemplate.opsForValue().get(RedisConstant.GOOD_BY_ID + id);
        //数据不为空则直接返回
        if (StrUtil.isNotBlank(sechandGoodsFromRedis)){
            SechandGoods sechandGoods = JsonUtils.jsonToPojo(sechandGoodsFromRedis, SechandGoods.class);
            return ResponseData.success(sechandGoods);
        }
        if ("".equals(sechandGoodsFromRedis)){
            return ResponseData.error(404, "请求商品非法");
        }
        //缓存未命中，则从数据库中获得
        SechandGoods sechandGoods = sechandGoodsService.selectSechandGoodsById(id);
        if (Objects.isNull(sechandGoods)) {
            //防止缓存穿透
            redisTemplate.opsForValue().set(RedisConstant.GOOD_BY_ID + id,"",5 + RedisConstant.getRandomSecond(), TimeUnit.SECONDS);
            return ResponseData.error(404, "请求商品非法");
        }
        //防止缓存雪崩
        redisTemplate.opsForValue().set(RedisConstant.GOOD_BY_ID + id
                ,JsonUtils.objectToJson(sechandGoods)
                ,60 + RedisConstant.getRandomSecond()
                , TimeUnit.SECONDS);
        return ResponseData.success(sechandGoods);
    }

    /**
     * 批量删除
     *
     * @param userId
     * @param sechandGoodsId
     * @param request
     * @return
     */
    @DeleteMapping("/deleteGoodsByUserId")
    public BaseResponse deleteGoodsByUserId(@RequestParam Integer userId,
                                            @RequestParam Integer sechandGoodsId,
                                            HttpServletRequest request) throws ServerException,
            InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        //获得当前登入的用户id
        WXSessionModel user = (WXSessionModel) request.getSession().getAttribute("user");
        Long userId1 = ThreadLocalUtil.get();
        WXSessionModel user1 = (WXSessionModel) redisUtil.get("user:" + userId);
        if (!(user.getUserId() > 0 && user.getUserId().equals(userId))) {
            return ResponseData.out(CodeEnum.BODY_NOT_MATCH, "删除商品失败");
        }
        //吧文件页删除吊
        SechandGoods sechandGoods = sechandGoodsService.selectSechandGoodsById(Long.valueOf(sechandGoodsId));
        minioSysFileService.deleteFiles(sechandGoods.getGoodsPhotos());
        int i = sechandGoodsService.deleteSechandGoods(sechandGoodsId, userId);
        if (i <= 0) {
            return ResponseData.out(CodeEnum.NOT_FOUND, "未找到商品，删除失败");
        }
        return ResponseData.success();
    }

    /**
     * 用户更新自己的闲置商品
     *
     * @param sechandGoods
     * @return
     */
//    @PutMapping("/updateGoods")
//    public BaseResponse updateGoods(
//            @RequestPart("files") MultipartFile[] files,
//            //@RequestParam("secHandGoods") String jsonStr,
//            @RequestPart("secHandGoods") SechandGoods sechandGoods,
//            HttpServletRequest request) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
//        //SechandGoods sechandGoods = JSON.parseObject(jsonStr, SechandGoods.class);
//        WXSessionModel user = (WXSessionModel) request.getSession().getAttribute("user");
//        sechandGoods.setUserId(Long.valueOf(user.getUserId()));
//        minioSysFileService.deleteFiles(sechandGoods.getGoodsPhotos());
//        //MultipartFile[] files = sechandGoods.getFiles();
//        //线程安全
//        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
//        CountDownLatch countDownLatch = new CountDownLatch(files.length);
//        for (int i = 0; i < files.length; i++) {
//            try {
//                MultipartFile file = files[i];
//                //TODO 使用CountDownLaunch或者ComplatableFuture或者Semaphore
//                //来完成多线程的文件上传
//                fileThreadPool.submit(() -> {
//                    try {
//                        String url = minioSysFileService.uploadFile(file);
//                        list.add(url);
//                    } catch (Exception e) {
//                        throw new RuntimeException(e);
//                    } finally {
//                        //表示一个文件已经被完成
//                        countDownLatch.countDown();
//                    }
//                });
//            } catch (Exception e) {
//                throw new RuntimeException(e);
//            }
//        }
//        try {
//            //阻塞直到所有的文件完成复制
//            countDownLatch.await();
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
//        //统计每个文件的url
//        String photoUrls = String.join(",", list);
//        sechandGoods.setGoodsPhotos(photoUrls);
//        int isUpdate = sechandGoodsService.updateSechandGoods(sechandGoods);
//        //if (isUpdate == 0) {
//        //    return ResponseData.error(CodeEnum.BODY_NOT_MATCH);
//        //}
//        return ResponseData.success(sechandGoods);
//    }

    @PostMapping("/updateGoods")
    public BaseResponse updateGoods(@RequestBody SechandGoods sechandGoods,
                                    HttpServletRequest request){
        WXSessionModel user = (WXSessionModel) request.getSession().getAttribute("user");
        Long userId = ThreadLocalUtil.get();
        WXSessionModel user1 = (WXSessionModel) redisUtil.get("user:" + userId);
        sechandGoods.setUserId(Long.valueOf(user.getUserId()));
        if (Objects.isNull(sechandGoods) || Strings.isNullOrEmpty(sechandGoods.getGoodsPhotos())){
            return ResponseData.error(CodeEnum.BODY_NOT_MATCH);
        }
        int i = sechandGoodsService.updateSechandGoods(sechandGoods);
        if (i <= 0){
            return ResponseData.error(CodeEnum.BODY_NOT_MATCH);
        }
        return ResponseData.success();
    }

    /**
     * 文件回显
     * @param name
     * @param response
     */
//    @GetMapping("/getPhoto")
//    public void getPhoto(@RequestParam("goodsPhotos") String name,
//                                 HttpServletResponse response){
//        try (ServletOutputStream os = response.getOutputStream()) {
//            response.setContentType("image/webp");
//            GetObjectResponse file = minioSysFileService.getFile(name);
////            压缩图片并且输出到resopnse输出流
//            Thumbnails.of(file)
//                    .scale(0.25f)
//                    .outputQuality(0.5f)
//                    .toOutputStream(os);
////            int len = 0;
////            byte[] buffre = new byte[1024 * 10];
////            while ((len = file.read(buffre)) != -1) {
////                os.write(buffre, 0, len);
////                os.flush();
////            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
    /**
     * 用户上传商品图片
     *
     * @param
     * @param
     * @return
     */
    @PostMapping("/uploadImage")
    public BaseResponse uploadZip(@RequestPart(value = "file",required = false)
                                      MultipartFile file) {
        String ossImageUrl = null;
        try {
            ossImageUrl = minioSysFileService.uploadFileWithZip(file);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return ResponseData.success(ossImageUrl);
    }

    @PostMapping("/saveGoods")
    public BaseResponse saveGoods(@RequestBody SechandGoods sechandGoods,
                                  HttpServletRequest request){
        WXSessionModel user = (WXSessionModel) request.getSession().getAttribute("user");
        Long userId = ThreadLocalUtil.get();
        WXSessionModel user1 = (WXSessionModel) redisUtil.get("user:" + userId);
        sechandGoods.setUserId(Long.valueOf(user.getUserId()));
        if (Objects.isNull(sechandGoods) || Strings.isNullOrEmpty(sechandGoods.getGoodsPhotos())){
            return ResponseData.error(CodeEnum.BODY_NOT_MATCH);
        }
        int i = sechandGoodsService.insertSechandGoods(sechandGoods);
        if (i <= 0){
            return ResponseData.error(CodeEnum.BODY_NOT_MATCH);
        }
        //删除首页缓存
        //TODO:可能会导致第二页没有原先第一页的数据，可以考虑将expire缩短，或者删去所有缓存
        redisUtil.del(RedisConstant.GOOD__PAGE_NO + "1");
        return ResponseData.success();
    }

    @PostMapping("/isBuy")
    public BaseResponse setGoodsIsBuy(@RequestParam Integer isBuy,
                                      @RequestParam Integer goodsId) {
        int i = sechandGoodsService.updateGoodsIsBuy(isBuy, Long.valueOf(goodsId));
        if (i <= 0) {
            return ResponseData.error(CodeEnum.NOT_FOUND);
        }
        return ResponseData.success();
    }

    /**
     * 通过关键字搜索商品(模糊查询)
     */
    @GetMapping("/getByKeyWord")
    public BaseResponse getGoodsByKeyWord(@RequestParam String keyword, @RequestParam Integer pageNo,
                                          @RequestParam Integer pageSize) {
        PageInfo<SechandGoods> goodsPageInfo = sechandGoodsService.selectSechandGoodsByKeyWord(keyword, pageNo,
                pageSize);
        return ResponseData.success(goodsPageInfo);
    }
    @GetMapping("/getGoodsByType")
    public BaseResponse getGoodsByType(@RequestParam Integer pageNo,
                                       @RequestParam Integer pageSize,
                                       @RequestParam Integer typeId){
        PageInfo<SechandGoods> sechandGoodsPageInfo = sechandGoodsService.selectGoodByTypeId(pageNo,pageSize,typeId);
        return ResponseData.success(sechandGoodsPageInfo);
    }
}

